//////////////////////////////////////////////////////////////////////////
//MODE Driver IC name : Hi3288 + C11
//Version: 1.0 Draft
//Time: 2022.09.19
//Description: Fake code run Hi3288 Flash process
//
//////////////////////////////////////////////////////////////////////////
void F_Hi3288_FLASH_GammaBinWrite(void)		//GammaBIN烧录
{
	printf("Begin to F_Hi3288_FLASH_Test");
	//将BCMG数据打包处理。
	Step1：把初始化代码中的BCMG LUT部分摘出(不包含地址)，并更新其中的Gamma数据，然后打包成 Gamma.bin 文件
		打包时注意为小端模式，低位在前，高位在后；举例如下
		LUT内容：
		0X0B328954, 0XE0E21630 //前面的0X0B328954 为地址，0xE0E21630为数据。
		0X0B328958, 0X00000011
		0X0B32895C, 0X270E8174
		0X0B328960, 0X00EE1851
		转换后的Gamma.bin内容为： 30 16 E2 E0 11 00 00 00 74 81 0E 27 51 18 EE 00

		//Step 2: 调用F_FLASH_COMMON_BIN_LOAD_TO_RAM，把Gamma.bin发送至RAM
		F_FLASH_COMMON_BIN_LOAD_TO_RAM("Gamma.bin")  //

		//Step 3: 读取FlashID确认无误后.通过下面函数执行FLASH-Write操作中，其会自动执行FLASH对应区域的檫除工作。
		F_Burn_GammaData_FlashBin();
	Delayms(50);
	printf("End of F_Hi3288_FLASH_Gammabin Write");
}

void F_Hi3288_FLASH_NoGammaBinwrite(void)  	//DemuraBIN烧录
{
	printf("Begin to F_Hi3288_FLASH_Test");
	Step1：读取Flash ID
		//Step 2: 调用F_FLASH_COMMON_BIN_LOAD_TO_RAM，把Gamma.bin发送至RAM
		F_FLASH_COMMON_BIN_LOAD_TO_RAM("FLASHBIN.bin")  //FLASHBIN.bin= Demura.bin
		//Step 3: 通过下面函数执行FLASH-Write操作中，其会自动执行FLASH对应区域的檫除工作。
		F_Burn_GammaData_FlashBin();
	Delayms(50);

	//Step 4: upload. 设定VI视频通路方式，并将FALSH.bin传递到DDIC-GRAM-0X0B000000地址上
	F_FLASH_COMMON_BIN_LOAD_TO_RAM();
	Delayms(50);
	//Step 5: burn NOGammaData_OtherFlashBin. 跳过0x3000的头区Gamma/BCMG数据。下面函数在FLASH-Write操作中，自动执行FLASH对应区域的檫除工作。
	F_Burn_NOGammaData_OtherFlashBin();
	printf("End of F_Hi3288_FLASH_DemuraBin Write");
}

void DDIC_Flash_Init(void)
{
	//step1  sf_init
	DDIC_Write_Register(0x01000010, 0x40101);
	DDIC_Write_Register(0x01000010, 0x40001);
	DDIC_Write_Register(0x0100003c, 0x1);
	DDIC_Write_Register(0x02005000, 0x1);
	DDIC_Write_Register(0x0200501c, 0x0);
	DDIC_Write_Register(0x02005020, 0x1ff);
	DDIC_Write_Register(0x02005048, 0xf);

	//step2 WREN  --disable-write-protect.
	DDIC_Write_Register(0x02005020, 0xff);
	DDIC_Write_Register(0x02005030, 0x0);
	DDIC_Write_Register(0x02005024, 0x06);
	DDIC_Write_Register(0x0200503c, 0x81);
	Delayms(100); //sleep 100 ms.
}

//读取FLASH-ID
int DDIC_Read_FlashID(void)
{
	int FlashID = 0;
	DDIC_Flash_Init();
	DDIC_Write_Register(0x01000010, 0x3);
	DDIC_Write_Register(0x0100003c, 0x1);
	DDIC_Write_Register(0x02005000, 0x1);
	DDIC_Write_Register(0x0200501c, 0x0);
	DDIC_Write_Register(0x02005020, 0x1ff);
	DDIC_Write_Register(0x02005048, 0xf);
	DDIC_Write_Register(0x02005030, 0x12);
	//read_id_command: 0x9f.
	DDIC_Write_Register(0x02005024, 0x9f);
	DDIC_Write_Register(0x02005038, 0x3);
	DDIC_Write_Register(0x0200503c, 0x85);

	//读0xc000000的低24bit就是flash的id
	FlashID = DDIC_Read_Register(0xc000000, 4);
	FlashID = FlashID & 0XFFFFFF;
	printf("FlashID is 0X08X\n", FlashID);

	return FlashID;
}

HI_U32 DDIC_EraseFlash(void)  //Flash 擦除
{
	DDIC_Flash_Init();

	//step2 WREN_CMD
	DDIC_Write_Register(0x02005020, 0xff);
	DDIC_Write_Register(0x02005030, 0x0);
	DDIC_Write_Register(0x02005024, 0x06);
	DDIC_Write_Register(0x0200503c, 0x81);
	// delay 100ms
	Delayms(100);

	//step3 sf_chip_erase
	DDIC_Write_Register(0x02005020, 0xff);
	DDIC_Write_Register(0x02005024, 0xc7);
	DDIC_Write_Register(0x02005030, 0x0);
	DDIC_Write_Register(0x0200503c, 0xC1);
	//读状态(循环下发24~3c配置，读取0xc000000的值，直到bit0=0跳出循环进行后续操作)
	printf("Delayms several minutes\n");
	Delayms(3000);
	HI_U32 readValue = 1;
	HI_U32 count = 0;
	while ((readValue & 0x1) != 0) {
		DDIC_Write_Register(0x02005024, 0x5);      //读flash状态寄存器低8bit
		DDIC_Write_Register(0x02005030, 0x00);
		DDIC_Write_Register(0x02005038, 0x1);
		DDIC_Write_Register(0x0200503c, 0x85);
		//delay 1ms
		Delayms(100);

		readValue = DDIC_Read_Register(0x0c000000, 4);
		printf("Read 0x0c000000 reg value : 0x%x", readValue);

		count = count + 1;
		if (count > 10) {
			printf("Error: Time out\n");
			return -1;
		}
	}
	printf("DDIC_EraseFlash ok\n");
	return 0;
}

HI_U32 F_Burn_GammaData_FlashBin(void)			//Gamma bin Write Flow
{
	DDIC_Flash_Init();
	//Now to test SPI-FLASHxxx IC burn spi-flash.
	HI_U32 flashID = 1;
	if (flashID == 0) {  //GD25xxx IC
		printf("GD25xxx IC\n");
		DDIC_Write_Register(0x02005020, 0xff);
		DDIC_Write_Register(0x02005030, 0x0);
		DDIC_Write_Register(0x02005024, 0x01);
		DDIC_Write_Register(0x02005004, 0x80);
		DDIC_Write_Register(0x02005038, 0x2);
		DDIC_Write_Register(0x0c000000, 0x200);
		DDIC_Write_Register(0x0200503c, 0xa1);
	}
	if (flashID == 1) {  //芯天下 IC
		printf("XTX IC\n");
		DDIC_Write_Register(0x02005020, 0xff);
		DDIC_Write_Register(0x02005030, 0x0);
		DDIC_Write_Register(0x02005024, 0x31);
		DDIC_Write_Register(0x02005004, 0x80);
		DDIC_Write_Register(0x02005038, 0x1);
		DDIC_Write_Register(0x0c000000, 0x2);
		DDIC_Write_Register(0x0200503c, 0xa1);
	}

	//delay 100ms
	Delayms(100);
	//step5 sf_write
	DDIC_Write_Register(0x02005020, 0xff);
	//delay 100ms
	Delayms(100);
	DDIC_Write_Register(0x0200502c, 0x0);
	DDIC_Write_Register(0x02005030, 0x1b0);

	printf("Write BCMG_LUT Offset:0x00, Datasize: 0x3000 Bytes");
	DDIC_Write_Register(0x02005380, 0x00);     //Offset: 0x00 Bytes-->for Gamma Flash
	DDIC_Write_Register(0x0200504c, 0x0B000000);//Gamma数据在RAM内的地址
	DDIC_Write_Register(0x02005068, 0x3202);
	DDIC_Write_Register(0x02005394, 0x18800005);
	DDIC_Write_Register(0x02005390, 0x0); //烧写长度为(0+1)*12KB;
	DDIC_Write_Register(0x050000c0, 0x1);	//使能
	Delayms(500);

	//重复读0x2005068的值，直到bit0=1
	HI_U32 readValue = DDIC_Read_Register(0x2005068, 4);
	Delayms(10);
	readValue = DDIC_Read_Register(0x2005068, 4);
	Delayms(10);
	readValue = DDIC_Read_Register(0x2005068, 4);
	Delayms(10);
	printf("Read 0x2005068 reg value : 0x%x", readValue);
	HI_U32 count = 0;
	while ((readValue & 0x1) == 0) {
		readValue = DDIC_Read_Register(0x2005068, 4);
		Delayms(10);
		readValue = DDIC_Read_Register(0x2005068, 4);
		Delayms(10);
		readValue = DDIC_Read_Register(0x2005068, 4);
		Delayms(10);
		printf("Read 0x2005068 reg value : 0x%x", readValue);

		count = count + 1;
		if (count > 10) {
			printf("Error: Time out\n");
			return -1;
		}
		Delayms(300);
	}

	printf("F_Burn_GammaData_FlashBin ok\n");
	return 0;
}

HI_U32 F_Burn_NOGammaData_OtherFlashBin(void) 	//Demura bin Write Flow
{
	DDIC_Flash_Init();

	//Now to test SPI-FLASHxxx IC burn spi-flash.
	HI_U32 flashID = 1;
	if (flashID == 0) {  //GD25xxx IC
		printf("GD25xxx IC\n");
		DDIC_Write_Register(0x02005020, 0xff);
		DDIC_Write_Register(0x02005030, 0x0);
		DDIC_Write_Register(0x02005024, 0x01);
		DDIC_Write_Register(0x02005004, 0x80);
		DDIC_Write_Register(0x02005038, 0x2);
		DDIC_Write_Register(0x0c000000, 0x200);
		DDIC_Write_Register(0x0200503c, 0xa1);
	}
	if (flashID == 1) { //芯天下 IC
		printf("XTX IC\n");
		DDIC_Write_Register(0x02005020, 0xff);
		DDIC_Write_Register(0x02005030, 0x0);
		DDIC_Write_Register(0x02005024, 0x31);
		DDIC_Write_Register(0x02005004, 0x80);
		DDIC_Write_Register(0x02005038, 0x1);
		DDIC_Write_Register(0x0c000000, 0x2);
		DDIC_Write_Register(0x0200503c, 0xa1);
	}

	//delay 100ms
	Delayms(100);
	//step5 sf_write
	DDIC_Write_Register(0x02005020, 0xff);
	//delay 100ms
	Delayms(100);
	DDIC_Write_Register(0x0200502c, 0x0);
	DDIC_Write_Register(0x02005030, 0x1b0);

	printf("Write Demura Offset:0x3000, Datasize: full Flash.bin Bytes");
	DDIC_Write_Register(0x02005380, 0x3000);     //Demurabin Offset: 0x3000 Bytes.-->12KB
	DDIC_Write_Register(0x0200504c, 0xB003000);   //skip the head of 0x3000 Bytes.
	DDIC_Write_Register(0x02005068, 0x3202);
	DDIC_Write_Register(0x02005394, 0x18800005);

	HI_U32 UnitNum = (FLASHBIN_ByteSize - 0x3000);
	if ((UnitNum % (12 * 1024)) == 0) {
		UnitNum = UnitNum / (12 * 1024);
	}
	else {
		UnitNum = UnitNum / (12 * 1024) + 1;
	}
	printf("DemuraDataByteNum:%d, Write 0x02005390 reg value : 0x%x", FLASHBIN_ByteSize, UnitNum);
	//0x02005390 dec2hex(UnitNum-1) 
	DDIC_Write_Register(0x02005390, (UnitNum - 1));
	DDIC_Write_Register(0x050000c0, 0x1);
	Delayms(500);

	//重复读0x2005068的值，直到bit0=1
	HI_U32 readValue = DDIC_Read_Register(0x2005068, 4);
	Delayms(10);
	readValue = DDIC_Read_Register(0x2005068, 4);
	Delayms(10);
	readValue = DDIC_Read_Register(0x2005068, 4);
	Delayms(10);
	printf("Read 0x2005068 reg value : 0x%x", readValue);
	HI_U32 count = 0;
	while ((readValue & 0x1) == 0) {
		readValue = DDIC_Read_Register(0x2005068, 4);
		Delayms(10);
		readValue = DDIC_Read_Register(0x2005068, 4);
		Delayms(10);
		readValue = DDIC_Read_Register(0x2005068, 4);
		Delayms(10);
		printf("Read 0x2005068 reg value : 0x%x", readValue);

		count = count + 1;
		if (count > 10) {
			printf("Error: Time out\n");
			return -1;
		}
		Delayms(300);
	}

	printf("F_Burn_NOGammaData_OtherFlashBin ok\n");
	return 0;
}

HI_U32 F_FLASH_COMMON_BIN_LOAD_TO_RAM("BinName.bin") 	//加载Bin文件至RAM
{

	HI_U32 size_packet = 96;    //write one packet  size ！重要！

	////--------INIT VI road to trans file --------////
	HI_U32 Org_Value_0X02006034 = DDIC_Read_Register(0X02006034, 4);
	HI_U32 Org_Value_0X05000000 = DDIC_Read_Register(0X05000000, 4);
	HI_U32 Org_Value_0X0500000C = DDIC_Read_Register(0X0500000C, 4);
	HI_U32 Org_Value_0X05000040 = DDIC_Read_Register(0X05000040, 4);
	HI_U32 Org_Value_0X05000014 = DDIC_Read_Register(0X05000014, 4);
	HI_U32 Org_Value_0X05000018 = DDIC_Read_Register(0X05000018, 4);
	HI_U32 Org_Value_0X05001000 = DDIC_Read_Register(0X05001000, 4);
	HI_U32 Org_Value_0X05002000 = DDIC_Read_Register(0X05002000, 4);
	HI_U32 Org_Value_0X0600C044 = DDIC_Read_Register(0X0600C044, 4);
	//trans data for VI road
	printf("trans data for VI road");
	DDIC_Write_Register(0X02006034, 0X00221100);
	DDIC_Write_Register(0X05000000, 0X02030003);
	DDIC_Write_Register(0X0500000C, 0X00000000);
	DDIC_Write_Register(0X05000040, 0X00010000);
	DDIC_Write_Register(0X05000014, 0X00000000);
	DDIC_Write_Register(0X05000018, 0X00000060);
	DDIC_Write_Register(0X05001000, 0X00000000);
	DDIC_Write_Register(0X05002000, 0X00000000);
	DDIC_Write_Register(0X0600C044, 0X40000000);

	//Reset!
	PG_MIPI_WRITE(0, 0x29, 0xFF, 0x00, 0x00, 0x00);  //mipi29包写入 FF,00,00,00
	Delayms(200);
	//FLASH_COMMON_BIN_LOAD_TO_RAM
	PG_LOADBIN("FLASHBIN.bin"); //以size_packet = 96 搬运Bin文件至RAM,尾部不足96字节填0
	//--------并获取FLASHBIN_ByteSize-供后续烧录使用----------
	printf("Load Visonox_xxx_FLASH_CRC_CheckEn.bin");

	//Reload defualt value. ,下方代码可以不执行
	printf("recover VI road config");
	DDIC_Write_Register(0X02006034, Org_Value_0X02006034);
	DDIC_Write_Register(0X05000000, Org_Value_0X05000000);
	DDIC_Write_Register(0X0500000C, Org_Value_0X0500000C);
	DDIC_Write_Register(0X05000040, Org_Value_0X05000040);
	DDIC_Write_Register(0X05000014, Org_Value_0X05000014);
	DDIC_Write_Register(0X05000018, Org_Value_0X05000018);
	DDIC_Write_Register(0X05001000, Org_Value_0X05001000);
	DDIC_Write_Register(0X05002000, Org_Value_0X05002000);
	DDIC_Write_Register(0X0600C044, Org_Value_0X0600C044);
}

